package com.ibm.framework.exception.utils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;

import com.ibm.framework.exception.BaseException;
import com.ibm.framework.exception.logger.ExceptionLogger;
import com.ibm.framework.exception.logger.LogMessageBuilder;
import com.ibm.framework.exception.model.ExceptionCode;

/**
 * 根据bean name 从ApplicationContext中获取bean实例的帮助类
 * 
 * 
 * @author matrixgan
 */
public class SpringBeanHelper {
    /**
     * 获取自定义的bean
     * 
     * @param name bean的名字
     * @param requiredType 匹配的类型
     * @param applicationContext 异常上下文
     * @return bean
     */
    public static <T> T getBean(String name, Class<T> requiredType, ApplicationContext applicationContext) {
        if (null == applicationContext) {
            return null;
        }
        T bean = null;
        try {
            bean = applicationContext.getBean(name, requiredType);
        } catch (NoSuchBeanDefinitionException exp) {
            String message = String.format("Bean [%s] no be defined.", name);
            String messageWithStacktrace = LogMessageBuilder.build(message, exp);
            ExceptionLogger.log(messageWithStacktrace);
        } catch (BeanNotOfRequiredTypeException ex) {
            String message = String.format("The type of bean [%s] is not the required type.", name);
            throw new BaseException(message, ex, ExceptionCode.INNER_EXCEPTION);
        } catch (BeansException ex) {
            String message = String.format("The bean [%s] could not be created.", name);
            throw new BaseException(message, ex, ExceptionCode.INNER_EXCEPTION);
        }
        return bean;
    }

    /**
     * 获取自定义的bean
     * 
     * @param requiredType 匹配的类型
     * @param applicationContext 应用上下文
     * @return 自定义bean
     */
    public static <T> T getBean(Class<T> requiredType, ApplicationContext applicationContext) {
        if (null == applicationContext) {
            return null;
        }
        T bean = null;
        try {
            bean = applicationContext.getBean(requiredType);
        } catch (NoSuchBeanDefinitionException exp) {
            String message = String.format("there is not exactly one matching bean [%s] found", requiredType);
            String messageWithStacktrace = LogMessageBuilder.build(message, exp);
            ExceptionLogger.log(messageWithStacktrace);
        } catch (BeansException ex) {
            String message = String.format("The bean [%s] could not be created.", requiredType);
            throw new BaseException(message, ex, ExceptionCode.INNER_EXCEPTION);
        }
        return bean;
    }

    /**
     * 私有构造函数SpringBeanHelper
     */
    private SpringBeanHelper() {

    }
}
